package pl.edu.pw.MidEmu.Common.Models;

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Vector;

import pl.edu.pw.MidEmu.Common.Consts;

/**
 * Model class representing MIDAS platform instance
 * Contains MIDAS settings
 * @author Mateusz Starodab
 *
 */
public class MidasModel extends ClassSettingsModel
{
	private static final long serialVersionUID = 5524712850692196851L;

	/**
	 * Loads MIDAS platform configuration from XML file
	 * @return
	 */
	public static MidasModel load()
	{
		MidasModel model = null;
		try
		{
			File file = new File(Consts.FilePath_MidasSettings);
			if (file.exists())
			{
				XMLDecoder decoder = new XMLDecoder(new BufferedInputStream(new FileInputStream(file)));
				model = (MidasModel) decoder.readObject();
				decoder.close();
			}
		}
		catch (FileNotFoundException ex)
		{
			ex.printStackTrace();
		}
		return model;
	}

	private String binariesDirectory;

	private String className;

	private String classPath;

	private transient String interfaceName;

	private transient String ipAddress;

	private transient Boolean isCentralNode;

	private transient String nodeName;

	private String parameters;
	
	private transient String temporaryDir;
	
	private String workDirectory;

	@Override
	/**
	 * check if two MIDAS platforms are same platform instance
	 * @return - True if MIDAS platforms are same instances
	 */
	public boolean equals(Object obj)
	{
		if (obj != null)
			if (obj instanceof MidasModel)
				return this.nodeName.equals(((MidasModel) obj).getNodeName());
		return false;
	}

	/**
	 * Gets binaries directory
	 * @return Binaries directory
	 */
	public String getBinariesDirectory()
	{
		return binariesDirectory;
	}

	@Override
	/**
	 * Gets MIDAS platform stettings for use with generic data grid
	 */
	public Vector<Vector<String>> getClassData()
	{
		Vector<Vector<String>> data = new Vector<Vector<String>>();

		addData(data, "Class name", className);
		addData(data, "Class path", classPath);
		addData(data, "Parameters", parameters);
		addData(data, "Node name", nodeName);
		addData(data, "Temporary directory", temporaryDir);
		addData(data, "Central node", isCentralNode.toString());
		addData(data, "Ip address", ipAddress);
		addData(data, "Interface name", interfaceName);
		addData(data, "Binaries directory", binariesDirectory);
		addData(data, "Working directory", workDirectory);

		return data;
	}

	/**
	 * Gets class name
	 * @return Calss name
	 */
	public String getClassName()
	{
		return className;
	}

	/**
	 * Gets class path
	 * @return Class path
	 */
	public String getClassPath()
	{
		return classPath;
	}

	/**
	 * Gets interface name
	 * @return Interface name
	 */
	public String getInterfaceName()
	{
		return interfaceName;
	}

	/**
	 * Gest IP address
	 * @return IP address
	 */
	public String getIpAddress()
	{
		return ipAddress;
	}

	/**
	 * Indicates if this MIDAS platform operates as central node
	 * @return True - if MIDAS platform is central node
	 */
	public Boolean getIsCentralNode()
	{
		return isCentralNode;
	}

	/**
	 * Gets node identifier
	 * @return Node identifier
	 */
	public String getNodeName()
	{
		return nodeName;
	}

	/**
	 * Gets command line parameters
	 * @return Command line parameters
	 */
	public String getParameters()
	{
		return parameters;
	}

	/**
	 * Gets temporary directory
	 * @return Temporary directory path
	 */
	public String getTemporaryDir()
	{
		return temporaryDir;
	}

	/**
	 * Gets work directory
	 * @return Work diorectory path
	 */
	public String getWorkDirectory()
	{
		return workDirectory;
	}

	@Override
	/**
	 * Gets hashcode
	 */
	public int hashCode()
	{
		return super.hashCode();
	}

	/**
	 * Save platform settings in XML file
	 */
	public void save()
	{
		try
		{
			XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(new FileOutputStream(Consts.FilePath_MidasSettings)));
			encoder.writeObject(this);
			encoder.close();
		}
		catch (FileNotFoundException ex)
		{
			ex.printStackTrace();
		}
	}

	/**
	 * Sets binaries directory
	 * @param binariesDirectory Binaries directory path
	 */
	public void setBinariesDirectory(String binariesDirectory)
	{
		this.binariesDirectory = binariesDirectory;
	}

	/**
	 * Sets main executable class name
	 * @param className Calss name
	 */
	public void setClassName(String className)
	{
		this.className = className;
	}

	/**
	 * Sets class path
	 * @param classPath Class path
	 */
	public void setClassPath(String classPath)
	{
		this.classPath = classPath;
	}

	/**
	 * Sets interface name
	 * @param interfaceName Interface name
	 */
	public void setInterfaceName(String interfaceName)
	{
		this.interfaceName = interfaceName;
	}

	/**
	 * Sets IP address
	 * @param ipAddress IP address
	 */
	public void setIpAddress(String ipAddress)
	{
		this.ipAddress = ipAddress;
	}

	/**
	 * Sets Central node flag
	 * @param isCentralNode Flag
	 */
	public void setIsCentralNode(Boolean isCentralNode)
	{
		this.isCentralNode = isCentralNode;
	}

	/**
	 * Sets node name
	 * @param nodeName Node name
	 */
	public void setNodeName(String nodeName)
	{
		this.nodeName = nodeName;
	}

	/**
	 * Sets command line parameters
	 * @param parameters Command line parameters
	 */
	public void setParameters(String parameters)
	{
		this.parameters = parameters;
	}

	/**
	 * Sets temporary directory
	 * @param temporaryDir Temporary directory path
	 */
	public void setTemporaryDir(String temporaryDir)
	{
		this.temporaryDir = temporaryDir;
	}

	/**
	 * Sets work directory
	 * @param workDirectory Work directory path
	 */
	public void setWorkDirectory(String workDirectory)
	{
		this.workDirectory = workDirectory;
	}

	@Override
	/**
	 * Returns string representation of this MIDAS platform
	 */
	public String toString()
	{
		return "MIDAS - " + nodeName + " (" + ipAddress + ")";
	}
}
